FieldLabelTypePair = (
    name : Identifier,
    isMutable : bool,
    `type` : TypeExpression
)

TypeExpression:
    Int8
    Int16
    Int32
    Int64

    UInt8
    UInt16
    UInt32
    UInt64

    Float32
    Float64

    Char8
    Char16
    Char32

    SByte
    Short
    Int
    Long

    Byte
    UShort
    UInt
    ULong

    IntPtrT
    UIntPtrT
    SizeT
    SSizeT
    PtrDiffT

    Float
    Double
    Decimal

    Bool
    Char

    String
    Object
    Dynamic

    Unit

    Tuple (elementTypes : [TypeExpression]+)
    Record (fields : [FieldLabelTypePair]+)
    ValueTuple (elementTypes : [TypeExpression]+)
    ValueRecord (fields : [FieldLabelTypePair]+)

    List (elementType : TypeExpression)
    Set (elementType : TypeExpression)
    Map (keyType : TypeExpression, valueType : TypeExpression)

    NameReference (name : Identifier)
    GlobalNameReference (name : Identifier)

    Access (operand : TypeExpression, member : Identifier)
    UnboundedGeneric (operand : TypeExpression, arity : int+)
    BoundedGeneric (operand : TypeExpression, arguments : [TypeExpression]+)

    NonNegativeInt8
    NonNegativeInt16
    NonNegativeInt32
    NonNegativeInt64

    NonNegativeFloat32
    NonNegativeFloat64

    NonNegativeSByte
    NonNegativeShort
    NonNegativeInt
    NonNegativeLong

    NonNegativeIntPtrT
    NonNegativeSSizeT
    NonNegativePtrDiffT

    NonNegativeFloat
    NonNegativeDouble
    NonNegativeDecimal

    PositiveInt8
    PositiveInt16
    PositiveInt32
    PositiveInt64

    PositiveFloat32
    PositiveFloat64

    PositiveSByte
    PositiveShort
    PositiveInt
    PositiveLong

    PositiveIntPtrT
    PositiveSSizeT
    PositiveDiffT

    PositiveFloat
    PositiveDouble
    PositiveDecimal

    MutableList (elementType : TypeExpression)
    MutableSet (elementType : TypeExpression)
    MutableMap (keyType : TypeExpression, valueType : TypeExpression)

    NonEmptyList (elementType : TypeExpression)
    NonEmptySet (elementType : TypeExpression)
    NonEmptyMap (keyType : TypeExpression, valueType : TypeExpression)

    NonEmptyMutableList (elementType : TypeExpression)
    NonEmptyMutableSet (elementType : TypeExpression)
    NonEmptyMutableMap (keyType : TypeExpression, valueType : TypeExpression)

    Nullable (operandType : TypeExpression)
    Union (elementTypes : [TypeExpression]+)
    Function (argumentType : TypeExpression, resultType : TypeExpression)

EnumItemDeclarator = (names : [Identifier]+)

StructFieldDeclarator = (
    name : Identifier,
    isMutable : bool,
    `type` : TypeExpression
)

UnionCaseDeclarator = (
    name : Identifier,
    fields : [StructFieldDeclarator],
	subcases : UnionCaseDeclaratorSuite?
)

UnionCaseDeclaratorSuite = (
    cases : [UnionCaseDeclarator]+,
    prefixFields : [StructFieldDeclarator],
    postfixFields : [StructFieldDeclarator]
)

InterfaceMemberDeclarator:
    Event (name : Identifier, `type` : TypeExpression)
    Property (name : Identifier, isMutable : bool, `type` : TypeExpression)
    Indexer (parameters : ParameterList, isMutable : bool, `type` : TypeExpression)
    Method (name : Identifier, parameters : ParameterList, resultType : TypeExpression?)

ClassMemberAccessibility: one of
    Public Protected Private Internal
    InternalProtected PrivateProtected
    NewPublic NewProtected NewPrivate NewInternal
    NewInternalProtected NewPrivateProtected
    New

ClassMemberVirtualModifier: one of
    Default Override Sealed

ClassVirtualModifier: one of
    Default Sealed Abstract Static Struct

ClassMethodBody:
    Expr (value : Expression)
    Block (actions : Statement)

ClassMemberDeclarator:
    Field (access : ClassMemberAccessibility, isStatic : bool, name : Identifier, isMutable : bool, `type` : TypeExpression, value : Expression?)

    Event (access : ClassMemberAccessibility, isStatic : bool, name : Identifier, `type` : TypeExpression)
    EventBlock (access : ClassMemberAccessibility, isStatic : bool, name : Identifier, `type` : TypeExpression, adder : ClassMethodBody, remover : ClassMethodBody?)
    VirtualEvent (access : ClassMemberAccessibility, modifier : ClassMemberVirtualModifier, name : Identifier, `type` : TypeExpression)
    VirtualEventBlock (access : ClassMemberAccessibility, modifier : ClassMemberVirtualModifier, name : Identifier, `type` : TypeExpression, adder : ClassMethodBody, remover : ClassMethodBody?)
    AbstractEvent (access : ClassMemberAccessibility, name : Identifier, `type` : TypeExpression)
    ExplicitEventImpl (target : TypeExpression, name : Identifier, `type` : TypeExpression)
    ExplicitEventImplBlock (target : TypeExpression, name : Identifier, `type` : TypeExpression, adder : ClassMethodBody, remover : ClassMethodBody?)

    Property (access : ClassMemberAccessibility, isStatic : bool, name : Identifier, `type` : TypeExpression, value : Expression)
    PropertyField (access : ClassMemberAccessibility, isStatic : bool, name : Identifier, isMutable : bool, `type` : TypeExpression, value : Expression?)
    PropertyBlock (access : ClassMemberAccessibility, isStatic : bool, name : Identifier, `type` : TypeExpression, getter : ClassMethodBody, setter : ClassMethodBody?)
    VirtualProperty (access : ClassMemberAccessibility, modifier : ClassMemberVirtualModifier, name : Identifier, `type` : TypeExpression, value : Expression)
    VirtualPropertyField (access : ClassMemberAccessibility, modifier : ClassMemberVirtualModifier, name : Identifier, isMutable : bool, `type` : TypeExpression, value : Expression?)
    VirtualPropertyBlock (access : ClassMemberAccessibility, modifier : ClassMemberVirtualModifier, name : Identifier, `type` : TypeExpression, getter : ClassMethodBody, setter : ClassMethodBody?)
    AbstractProperty (access : ClassMemberAccessibility, name : Identifier, isMutable : bool, `type` : TypeExpression)
    ExplicitPropertyImpl (target : TypeExpression, name : Identifier, `type` : TypeExpression, value : Expression)
    ExplicitPropertyImplField (target : TypeExpression, name : Identifier, isMutable : bool, `type` : TypeExpression, value : Expression?)
    ExplicitPropertyImplBlock (target : TypeExpression, name : Identifier, `type` : TypeExpression, getter : ClassMethodBody, setter : ClassMethodBody?)

    Indexer (access : ClassMemberAccessibility, parameters : ParameterList, `type` : TypeExpression, value : Expression)
    IndexerBlock (access : ClassMemberAccessibility, parameters : ParameterList, `type` : TypeExpression, getter : ClassMethodBody, setter : ClassMethodBody?)
    VirtualIndexer (access : ClassMemberAccessibility, modifier : ClassMemberVirtualModifier, parameters : ParameterList, `type` : TypeExpression, value : Expression)
    VirtualIndexerBlock (access : ClassMemberAccessibility, modifier : ClassMemberVirtualModifier, parameters : ParameterList, `type` : TypeExpression, getter : ClassMethodBody, setter : ClassMethodBody?)
    AbstractIndexer (access : ClassMemberAccessibility, parameters : ParameterList, isMutable : bool, `type` : TypeExpression)
    ExplicitIndexerImpl (target : TypeExpression, parameters : ParameterList, `type` : TypeExpression, value : Expression)
    ExplicitIndexerImplBlock (target : TypeExpression, parameters : ParameterList, `type` : TypeExpression, getter : ClassMethodBody, setter : ClassMethodBody?)

    Method (access : ClassMemberAccessibility, isAsync : bool, isStatic : bool, name : Identifier, parameters : ParameterList, resultType : TypeExpression?, body : ClassMethodBody)
    VirtualMethod (access : ClassMemberAccessibility, isAsync : bool, modifier : ClassMemberVirtualModifier, name : Identifier, parameters : ParameterList, resultType : TypeExpression?, body : ClassMethodBody)
    AbstractMethod (access : ClassMemberAccessibility, name : Identifier, parameters : ParameterList, resultType : TypeExpression?)
    ExplicitMethodImpl (isAsync : bool, target : TypeExpression, name : Identifier, parameters : ParameterList, resultType : TypeExpression?, body : ClassMethodBody)

    Constructor (access : ClassMemberAccessibility, parameters : ParameterList, body : ClassMethodBody)
    ConstructorWithThis (access : ClassMemberAccessibility, parameters : ParameterList, arguments : ArgumentList, body : ClassMethodBody)
    ConstructorWithBase (access : ClassMemberAccessibility, parameters : ParameterList, arguments : ArgumentList, body : ClassMethodBody)
    StaticConstructor (body : ClassMethodBody)

EnumDeclarator = (
    isInternal : bool,
    name : Identifier,
    isReversed: bool,
    items : [EnumItemDeclarator]+
)

StructDeclarator = (
    isInternal : bool,
    name : Identifier,
    fields : [StructFieldDeclarator]+,
    isValueType : bool
)

UnionDeclarator = (
    isInternal : bool,
    name : Identifier,
    cases : UnionCaseDeclaratorSuite
)

VisitorDeclarator = (
    isInternal : bool,
    name : Identifier,
    methodNamePrefix : Identifier,
    parameters : ParameterList,
    resultType : TypeExpression?
)

InterfaceDeclarator = (
    isInternal : bool,
    name : Identifier,
    bases : [TypeExpression],
    members : [InterfaceMemberDeclarator]
)

ClassDeclarator = (
    isInternal : bool,
    modifier : ClassVirtualModifier,
    name : Identifier,
    bases : [TypeExpression],
    members : [ClassMemberDeclarator]
)

TypeDeclarator:
    Enum (declarator : EnumDeclarator)
    Struct (declarator : StructDeclarator)
    Union (declarator : UnionDeclarator)
    Visitor (declarator : VisitorDeclarator)
    Interface (declarator : InterfaceDeclarator)
    Class (declarator : ClassDeclarator)
    attributes (isInternal : bool, name : Identifier)

TypeDeclaration = (declarators : [TypeDeclarator])

%%

FieldLabelTypePair as FieldLabelTypePair:
    Name ':' TypeExpression => FieldLabelTypePair.New($1, False, $3, @@)
    Name '!' ':' TypeExpression => FieldLabelTypePair.New($1, True, $4, @@)

BuiltinTypeExpression as TypeExpression:
    'int8' => TypeExpression.NewInt8(@@)
    'int16' => TypeExpression.NewInt16(@@)
    'int32' => TypeExpression.NewInt32(@@)
    'int64' => TypeExpression.NewInt64(@@)

    'uint8' => TypeExpression.NewUInt8(@@)
    'uint16' => TypeExpression.NewUInt16(@@)
    'uint32' => TypeExpression.NewUInt32(@@)
    'uint64' => TypeExpression.NewUInt64(@@)

    'float32' => TypeExpression.NewFloat32(@@)
    'float64' => TypeExpression.NewFloat64(@@)

    'char8' => TypeExpression.NewChar8(@@)
    'char16' => TypeExpression.NewChar16(@@)
    'char32' => TypeExpression.NewChar32(@@)

    'sbyte' => TypeExpression.NewSByte(@@)
    'short' => TypeExpression.NewShort(@@)
    'int' => TypeExpression.NewInt(@@)
    'long' => TypeExpression.NewLong(@@)

    'byte' => TypeExpression.NewByte(@@)
    'ushort' => TypeExpression.NewUShort(@@)
    'uint' => TypeExpression.NewUInt(@@)
    'ulong' => TypeExpression.NewULong(@@)

    'intptr_t' => TypeExpression.NewIntPtrT(@@)
    'uintptr_t' => TypeExpression.NewUIntPtrT(@@)
    'size_t' => TypeExpression.NewSizeT(@@)
    'ssize_t' => TypeExpression.NewSSizeT(@@)
    'ptrdiff_t' => TypeExpression.NewPtrDiffT(@@)

    'float' => TypeExpression.NewFloat(@@)
    'double' => TypeExpression.NewDouble(@@)
    'decimal' => TypeExpression.NewDecimal(@@)

    'bool' => TypeExpression.NewBool(@@)
    'char' => TypeExpression.NewChar(@@)

    'string' => TypeExpression.NewString(@@)
    'object' => TypeExpression.NewObject(@@)
    'dynamic' => TypeExpression.NewDynamic(@@)

PrimaryTypeExpression as TypeExpression:
    BuiltinTypeExpression => $1

    '(' ')' => TypeExpression.NewUnit(@@)
    '(' TypeExpression ')' => $2

    '(' TypeExpression ',' ')' => TypeExpression.NewTuple(Sequence.Create($2), @@)
    '(' TypeExpression ',' TypeExpression %+ ',' ','? ')' => TypeExpression.NewTuple(Sequence.Prepend($2, $4), @@)
    '(' FieldLabelTypePair %+ ',' ','? ')' => TypeExpression.NewRecord($2, @@)
    'struct' '(' TypeExpression %+ ',' ','? ')' => TypeExpression.NewValueTuple($3, @@)
    'struct' '(' FieldLabelTypePair %+ ',' ','? ')' => TypeExpression.NewValueRecord($3, @@)

    '[' TypeExpression ']' => TypeExpression.NewList($2, @@)
    '{' TypeExpression '}' => TypeExpression.NewSet($2, @@)
    '{' TypeExpression ':' TypeExpression '}' => TypeExpression.NewMap($2, $4, @@)

    Name => TypeExpression.NewNameReference($1, @1)
    'global' '::' Name => TypeExpression.NewGlobalNameReference($3, @@)

PostfixTypeExpression as TypeExpression:
    PrimaryTypeExpression => $1

    PostfixTypeExpression '.' Name => TypeExpression.NewAccess($1, $3, @@)
    PostfixTypeExpression '[' ']' => TypeExpression.NewUnboundedGeneric($1, 1, @@)
    PostfixTypeExpression '[' CommaCounter ']' => TypeExpression.NewUnboundedGeneric($1, $3 + 1, @@)
    PostfixTypeExpression '[' TypeExpression %+ ',' ']' => TypeExpression.NewBoundedGeneric($1, $3, @@)

    'int8' '*' => TypeExpression.NewNonNegativeInt8(@@)
    'int16' '*' => TypeExpression.NewNonNegativeInt16(@@)
    'int32' '*' => TypeExpression.NewNonNegativeInt32(@@)
    'int64' '*' => TypeExpression.NewNonNegativeInt64(@@)

    'float32' '*' => TypeExpression.NewNonNegativeFloat32(@@)
    'float64' '*' => TypeExpression.NewNonNegativeFloat64(@@)

    'sbyte' '*' => TypeExpression.NewNonNegativeSByte(@@)
    'short' '*' => TypeExpression.NewNonNegativeShort(@@)
    'int' '*' => TypeExpression.NewNonNegativeInt(@@)
    'long' '*' => TypeExpression.NewNonNegativeLong(@@)

    'intptr_t' '*' => TypeExpression.NewNonNegativeIntPtrT(@@)
    'ssize_t' '*' => TypeExpression.NewNonNegativeSSizeT(@@)
    'ptrdiff_t' '*' => TypeExpression.NewNonNegativePtrDiffT(@@)

    'float' '*' => TypeExpression.NewNonNegativeFloat(@@)
    'double' '*' => TypeExpression.NewNonNegativeDouble(@@)
    'decimal' '*' => TypeExpression.NewNonNegativeDecimal(@@)

    'int8' '+' => TypeExpression.NewPositiveInt8(@@)
    'int16' '+' => TypeExpression.NewPositiveInt16(@@)
    'int32' '+' => TypeExpression.NewPositiveInt32(@@)
    'int64' '+' => TypeExpression.NewPositiveInt64(@@)

    'float32' '+' => TypeExpression.NewPositiveFloat32(@@)
    'float64' '+' => TypeExpression.NewPositiveFloat64(@@)

    'sbyte' '+' => TypeExpression.NewPositiveSByte(@@)
    'short' '+' => TypeExpression.NewPositiveShort(@@)
    'int' '+' => TypeExpression.NewPositiveInt(@@)
    'long' '+' => TypeExpression.NewPositiveLong(@@)

    'intptr_t' '+' => TypeExpression.NewPositiveIntPtrT(@@)
    'ssize_t' '+' => TypeExpression.NewPositiveSSizeT(@@)
    'ptrdiff_t' '+' => TypeExpression.NewPositiveDiffT(@@)

    'float' '+' => TypeExpression.NewPositiveFloat(@@)
    'double' '+' => TypeExpression.NewPositiveDouble(@@)
    'decimal' '+' => TypeExpression.NewPositiveDecimal(@@)

    '[' TypeExpression ']' '!' => TypeExpression.NewMutableList($2, @@)
    '{' TypeExpression '}' '!' => TypeExpression.NewMutableSet($2, @@)
    '{' TypeExpression ':' TypeExpression '}' '!' => TypeExpression.NewMutableMap($2, $4, @@)

    '[' TypeExpression ']' '+' => TypeExpression.NewNonEmptyList($2, @@)
    '{' TypeExpression '}' '+' => TypeExpression.NewNonEmptySet($2, @@)
    '{' TypeExpression ':' TypeExpression '}' '+' => TypeExpression.NewNonEmptyMap($2, $4, @@)

    '[' TypeExpression ']' '!' '+' => TypeExpression.NewNonEmptyMutableList($2, @@)
    '{' TypeExpression '}' '!' '+' => TypeExpression.NewNonEmptyMutableSet($2, @@)
    '{' TypeExpression ':' TypeExpression '}' '!' '+' => TypeExpression.NewNonEmptyMutableMap($2, $4, @@)

    PostfixTypeExpression '?' => TypeExpression.NewNullable($1, @@)

UnionTypeExpression as TypeExpression:
    PostfixTypeExpression => $1
    PostfixTypeExpression '|' PostfixTypeExpression %+ '|' => TypeExpression.NewUnion(Sequence.Prepend($1, $3), @@)

FunctionTypeExpression as TypeExpression:
    UnionTypeExpression => $1
    UnionTypeExpression '->' FunctionTypeExpression => TypeExpression.NewFunction($1, $3, @@)

TypeExpression as TypeExpression:
    FunctionTypeExpression => $1

CommaCounter as int:
    ',' => 1
    CommaCounter ',' => $1 + 1

EnumItemDeclarator as EnumItemDeclarator:
    Name+ NewLine => EnumItemDeclarator.New($1, @@)

StructFieldDeclarator as StructFieldDeclarator:
    Name ':' TypeExpression => StructFieldDeclarator.New($1, False, $3, @@)
    Name '!' ':' TypeExpression => StructFieldDeclarator.New($1, True, $4, @@)

UnionCaseDeclarator as UnionCaseDeclarator:
    Name NewLine => UnionCaseDeclarator.New($1, default([StructFieldDeclarator]), None, @@)
    Name '(' StructFieldDeclarator %+ ',' ')' NewLine => UnionCaseDeclarator.New($1, $3, None, @@)
    Name ':' NewLine Indent UnionCaseDeclaratorSuite Unindent => UnionCaseDeclarator.New($1, default([StructFieldDeclarator]), $5, @@)
    Name '(' StructFieldDeclarator %+ ',' ')' ':' NewLine Indent UnionCaseDeclaratorSuite Unindent => UnionCaseDeclarator.New($1, $3, $8, @@)

UnionPrefixFieldList as [StructFieldDeclarator]:
    => default([StructFieldDeclarator])
    'attributes' '(' StructFieldDeclarator %+ ',' ')' NewLine => $3

UnionPostfixFieldList as [StructFieldDeclarator]:
    => default([StructFieldDeclarator])
    'attributes!' '(' StructFieldDeclarator %+ ',' ')' NewLine => $3

UnionCaseDeclaratorSuite as UnionCaseDeclaratorSuite:
    UnionCaseDeclarator+ UnionPrefixFieldList UnionPostfixFieldList => UnionCaseDeclaratorSuite.New($1, $2, $3, @@)

InterfaceMemberDeclarator as InterfaceMemberDeclarator:
    'event' Name ':' TypeExpression NewLine => InterfaceMemberDeclarator.NewEvent($2, $4, @@)
    Name ':' TypeExpression NewLine => InterfaceMemberDeclarator.NewProperty($1, False, $3, @@)
    Name '!' ':' TypeExpression NewLine => InterfaceMemberDeclarator.NewProperty($1, True, $4, @@)
    'this' '[' ParameterList ']' ':' TypeExpression NewLine => InterfaceMemberDeclarator.NewIndexer($3, False, $6, @@)
    'this' '[' ParameterList ']' '!' ':' TypeExpression NewLine => InterfaceMemberDeclarator.NewIndexer($3, True, $7, @@)
    Name '(' ParameterList ')' NewLine => InterfaceMemberDeclarator.NewMethod($1, $3, None, @@)
    Name '(' ParameterList ')' '->' TypeExpression NewLine => InterfaceMemberDeclarator.NewMethod($1, $3, $6, @@)
    
ClassMemberAccessibility as ClassMemberAccessibility:
    'public' => ClassMemberAccessibility.Public
    'protected' => ClassMemberAccessibility.Protected
    'private' => ClassMemberAccessibility.Private
    'internal' => ClassMemberAccessibility.Internal
    'internal' 'protected' => ClassMemberAccessibility.InternalProtected
    'protected' 'internal' => ClassMemberAccessibility.InternalProtected
    'private' 'protected' => ClassMemberAccessibility.PrivateProtected
    'protected' 'private' => ClassMemberAccessibility.PrivateProtected
    'new' 'public' => ClassMemberAccessibility.NewPublic
    'new' 'protected' => ClassMemberAccessibility.NewProtected
    'new' 'private' => ClassMemberAccessibility.NewPrivate
    'new' 'internal' => ClassMemberAccessibility.NewInternal
    'new' 'internal' 'protected' => ClassMemberAccessibility.NewInternalProtected
    'new' 'protected' 'internal' => ClassMemberAccessibility.NewInternalProtected
    'new' 'private' 'protected' => ClassMemberAccessibility.NewPrivateProtected
    'new' 'protected' 'private' => ClassMemberAccessibility.NewPrivateProtected
    'new' => ClassMemberAccessibility.New

ClassMemberVirtualModifier as ClassMemberVirtualModifier:
    'default' => ClassMemberVirtualModifier.Default
    'override' => ClassMemberVirtualModifier.Override
    'sealed' => ClassMemberVirtualModifier.Sealed

ClassVirtualModifier as ClassVirtualModifier:
    'class' => ClassVirtualModifier.Sealed
    'default' 'class' => ClassVirtualModifier.Default
    'sealed' 'class' => ClassVirtualModifier.Sealed
    'abstract' 'class' => ClassVirtualModifier.Abstract
    'static' 'class' => ClassVirtualModifier.Static
    'struct' => ClassVirtualModifier.Struct

ClassMethodBody as ClassMethodBody:
    '=>' TestExpression NewLine => ClassMethodBody.NewExpr($2, @@)
    SuiteStatement => ClassMethodBody.NewBlock($1, @1)

ClassMemberDeclarator as ClassMemberDeclarator:
    'field' Name ':' TypeExpression NewLine => ClassMemberDeclarator.NewField(ClassMemberAccessibility.Private, False, $2, False, $4, None, @@)
    'field' Name ':' TypeExpression '=' TestExpression NewLine => ClassMemberDeclarator.NewField(ClassMemberAccessibility.Private, False, $2, False, $4, $6, @@)
    'field' Name '!' ':' TypeExpression NewLine => ClassMemberDeclarator.NewField(ClassMemberAccessibility.Private, False, $2, True, $5, None, @@)
    'field' Name '!' ':' TypeExpression '=' TestExpression NewLine => ClassMemberDeclarator.NewField(ClassMemberAccessibility.Private, False, $2, True, $5, $7, @@)
    'static' 'field' Name ':' TypeExpression NewLine => ClassMemberDeclarator.NewField(ClassMemberAccessibility.Private, True, $3, False, $5, None, @@)
    'static' 'field' Name ':' TypeExpression '=' TestExpression NewLine => ClassMemberDeclarator.NewField(ClassMemberAccessibility.Private, True, $3, False, $5, $7, @@)
    'static' 'field' Name '!' ':' TypeExpression NewLine => ClassMemberDeclarator.NewField(ClassMemberAccessibility.Private, True, $3, True, $6, None, @@)
    'static' 'field' Name '!' ':' TypeExpression '=' TestExpression NewLine => ClassMemberDeclarator.NewField(ClassMemberAccessibility.Private, True, $3, True, $6, $8, @@)

    ClassMemberAccessibility 'field' Name ':' TypeExpression NewLine => ClassMemberDeclarator.NewField($1, False, $3, False, $5, None, @@)
    ClassMemberAccessibility 'field' Name ':' TypeExpression '=' TestExpression NewLine => ClassMemberDeclarator.NewField($1, False, $3, False, $5, $7, @@)
    ClassMemberAccessibility 'field' Name '!' ':' TypeExpression NewLine => ClassMemberDeclarator.NewField($1, False, $3, True, $6, None, @@)
    ClassMemberAccessibility 'field' Name '!' ':' TypeExpression '=' TestExpression NewLine => ClassMemberDeclarator.NewField($1, False, $3, True, $6, $8, @@)
    ClassMemberAccessibility 'static' 'field' Name ':' TypeExpression NewLine => ClassMemberDeclarator.NewField($1, True, $4, False, $6, None, @@)
    ClassMemberAccessibility 'static' 'field' Name ':' TypeExpression '=' TestExpression NewLine => ClassMemberDeclarator.NewField($1, True, $4, False, $6, $8, @@)
    ClassMemberAccessibility 'static' 'field' Name '!' ':' TypeExpression NewLine => ClassMemberDeclarator.NewField($1, True, $4, True, $7, None, @@)
    ClassMemberAccessibility 'static' 'field' Name '!' ':' TypeExpression '=' TestExpression NewLine => ClassMemberDeclarator.NewField($1, True, $4, True, $7, $9, @@)

    'event' Name ':' TypeExpression NewLine => ClassMemberDeclarator.NewEvent(ClassMemberAccessibility.Public, False, $2, $4, @@)
    'event' Name ':' TypeExpression 'with' NewLine Indent 'add' ClassMethodBody Unindent => ClassMemberDeclarator.NewEventBlock(ClassMemberAccessibility.Public, False, $2, $4, $9, None, @@)
    'event' Name ':' TypeExpression 'with' NewLine Indent 'add' ClassMethodBody 'remove' ClassMethodBody Unindent => ClassMemberDeclarator.NewEventBlock(ClassMemberAccessibility.Public, False, $2, $4, $9, $11, @@)
    'static' 'event' Name ':' TypeExpression NewLine => ClassMemberDeclarator.NewEvent(ClassMemberAccessibility.Public, True, $3, $5, @@)
    'static' 'event' Name ':' TypeExpression 'with' NewLine Indent 'add' ClassMethodBody Unindent => ClassMemberDeclarator.NewEventBlock(ClassMemberAccessibility.Public, True, $3, $5, $10, None, @@)
    'static' 'event' Name ':' TypeExpression 'with' NewLine Indent 'add' ClassMethodBody 'remove' ClassMethodBody Unindent => ClassMemberDeclarator.NewEventBlock(ClassMemberAccessibility.Public, True, $3, $5, $10, $12, @@)
    ClassMemberVirtualModifier 'event' Name ':' TypeExpression NewLine => ClassMemberDeclarator.NewVirtualEvent(ClassMemberAccessibility.Public, $1, $3, $5, @@)
    ClassMemberVirtualModifier 'event' Name ':' TypeExpression 'with' NewLine Indent 'add' ClassMethodBody Unindent => ClassMemberDeclarator.NewVirtualEventBlock(ClassMemberAccessibility.Public, $1, $3, $5, $10, None, @@)
    ClassMemberVirtualModifier 'event' Name ':' TypeExpression 'with' NewLine Indent 'add' ClassMethodBody 'remove' ClassMethodBody Unindent => ClassMemberDeclarator.NewVirtualEventBlock(ClassMemberAccessibility.Public, $1, $3, $5, $10, $12, @@)
    'abstract' 'event' Name ':' TypeExpression NewLine => ClassMemberDeclarator.NewAbstractEvent(ClassMemberAccessibility.Public, $3, $5, @@)

    ClassMemberAccessibility 'event' Name ':' TypeExpression NewLine => ClassMemberDeclarator.NewEvent($1, False, $3, $5, @@)
    ClassMemberAccessibility 'event' Name ':' TypeExpression 'with' NewLine Indent 'add' ClassMethodBody Unindent => ClassMemberDeclarator.NewEventBlock($1, False, $3, $5, $10, None, @@)
    ClassMemberAccessibility 'event' Name ':' TypeExpression 'with' NewLine Indent 'add' ClassMethodBody 'remove' ClassMethodBody Unindent => ClassMemberDeclarator.NewEventBlock($1, False, $3, $5, $10, $12, @@)
    ClassMemberAccessibility 'static' 'event' Name ':' TypeExpression NewLine => ClassMemberDeclarator.NewEvent($1, True, $4, $6, @@)
    ClassMemberAccessibility 'static' 'event' Name ':' TypeExpression 'with' NewLine Indent 'add' ClassMethodBody Unindent => ClassMemberDeclarator.NewEventBlock($1, True, $4, $6, $11, None, @@)
    ClassMemberAccessibility 'static' 'event' Name ':' TypeExpression 'with' NewLine Indent 'add' ClassMethodBody 'remove' ClassMethodBody Unindent => ClassMemberDeclarator.NewEventBlock($1, True, $4, $6, $11, $13, @@)
    ClassMemberAccessibility ClassMemberVirtualModifier 'event' Name ':' TypeExpression NewLine => ClassMemberDeclarator.NewVirtualEvent($1, $2, $4, $6, @@)
    ClassMemberAccessibility ClassMemberVirtualModifier 'event' Name ':' TypeExpression 'with' NewLine Indent 'add' ClassMethodBody Unindent => ClassMemberDeclarator.NewVirtualEventBlock($1, $2, $4, $6, $11, None, @@)
    ClassMemberAccessibility ClassMemberVirtualModifier 'event' Name ':' TypeExpression 'with' NewLine Indent 'add' ClassMethodBody 'remove' ClassMethodBody Unindent => ClassMemberDeclarator.NewVirtualEventBlock($1, $2, $4, $6, $11, $13, @@)
    ClassMemberAccessibility 'abstract' 'event' Name ':' TypeExpression NewLine => ClassMemberDeclarator.NewAbstractEvent($1, $4, $6, @@)

    'event' TypeExpression '::' Name ':' TypeExpression NewLine => ClassMemberDeclarator.NewExplicitEventImpl($2, $4, $6, @@)
    'event' TypeExpression '::' Name ':' TypeExpression 'with' NewLine Indent 'add' ClassMethodBody Unindent => ClassMemberDeclarator.NewExplicitEventImplBlock($2, $4, $6, $11, None, @@)
    'event' TypeExpression '::' Name ':' TypeExpression 'with' NewLine Indent 'add' ClassMethodBody 'remove' ClassMethodBody Unindent => ClassMemberDeclarator.NewExplicitEventImplBlock($2, $4, $6, $11, $13, @@)

    Name ':' TypeExpression '=>' TestExpression NewLine => ClassMemberDeclarator.NewProperty(ClassMemberAccessibility.Public, False, $1, $3, $5, @@)
    Name ':' TypeExpression NewLine => ClassMemberDeclarator.NewPropertyField(ClassMemberAccessibility.Public, False, $1, False, $3, None, @@)
    Name ':' TypeExpression '=' TestExpression NewLine => ClassMemberDeclarator.NewPropertyField(ClassMemberAccessibility.Public, False, $1, False, $3, $5, @@)
    Name '!' ':' TypeExpression NewLine => ClassMemberDeclarator.NewPropertyField(ClassMemberAccessibility.Public, False, $1, True, $4, None, @@)
    Name '!' ':' TypeExpression '=' TestExpression NewLine => ClassMemberDeclarator.NewPropertyField(ClassMemberAccessibility.Public, False, $1, True, $4, $6, @@)
    Name ':' TypeExpression 'with' NewLine Indent 'get' ClassMethodBody Unindent => ClassMemberDeclarator.NewPropertyBlock(ClassMemberAccessibility.Public, False, $1, $3, $8, None, @@)
    Name ':' TypeExpression 'with' NewLine Indent 'get' ClassMethodBody 'set' ClassMethodBody Unindent => ClassMemberDeclarator.NewPropertyBlock(ClassMemberAccessibility.Public, False, $1, $3, $8, $10, @@)
    'static' Name ':' TypeExpression '=>' TestExpression NewLine => ClassMemberDeclarator.NewProperty(ClassMemberAccessibility.Public, True, $2, $4, $6, @@)
    'static' Name ':' TypeExpression NewLine => ClassMemberDeclarator.NewPropertyField(ClassMemberAccessibility.Public, True, $2, False, $4, None, @@)
    'static' Name ':' TypeExpression '=' TestExpression NewLine => ClassMemberDeclarator.NewPropertyField(ClassMemberAccessibility.Public, True, $2, False, $4, $6, @@)
    'static' Name '!' ':' TypeExpression NewLine => ClassMemberDeclarator.NewPropertyField(ClassMemberAccessibility.Public, True, $2, True, $5, None, @@)
    'static' Name '!' ':' TypeExpression '=' TestExpression NewLine => ClassMemberDeclarator.NewPropertyField(ClassMemberAccessibility.Public, True, $2, True, $5, $7, @@)
    'static' Name ':' TypeExpression 'with' NewLine Indent 'get' ClassMethodBody Unindent => ClassMemberDeclarator.NewPropertyBlock(ClassMemberAccessibility.Public, True, $2, $4, $9, None, @@)
    'static' Name ':' TypeExpression 'with' NewLine Indent 'get' ClassMethodBody 'set' ClassMethodBody Unindent => ClassMemberDeclarator.NewPropertyBlock(ClassMemberAccessibility.Public, True, $2, $4, $9, $11, @@)
    ClassMemberVirtualModifier Name ':' TypeExpression '=>' TestExpression NewLine => ClassMemberDeclarator.NewVirtualProperty(ClassMemberAccessibility.Public, $1, $2, $4, $6, @@)
    ClassMemberVirtualModifier Name ':' TypeExpression NewLine => ClassMemberDeclarator.NewVirtualPropertyField(ClassMemberAccessibility.Public, $1, $2, False, $4, None, @@)
    ClassMemberVirtualModifier Name ':' TypeExpression '=' TestExpression NewLine => ClassMemberDeclarator.NewVirtualPropertyField(ClassMemberAccessibility.Public, $1, $2, False, $4, $6, @@)
    ClassMemberVirtualModifier Name '!' ':' TypeExpression NewLine => ClassMemberDeclarator.NewVirtualPropertyField(ClassMemberAccessibility.Public, $1, $2, True, $5, None, @@)
    ClassMemberVirtualModifier Name '!' ':' TypeExpression '=' TestExpression NewLine => ClassMemberDeclarator.NewVirtualPropertyField(ClassMemberAccessibility.Public, $1, $2, True, $5, $7, @@)
    ClassMemberVirtualModifier Name ':' TypeExpression 'with' NewLine Indent 'get' ClassMethodBody Unindent => ClassMemberDeclarator.NewVirtualPropertyBlock(ClassMemberAccessibility.Public, $1, $2, $4, $9, None, @@)
    ClassMemberVirtualModifier Name ':' TypeExpression 'with' NewLine Indent 'get' ClassMethodBody 'set' ClassMethodBody Unindent => ClassMemberDeclarator.NewVirtualPropertyBlock(ClassMemberAccessibility.Public, $1, $2, $4, $9, $11, @@)
    'abstract' Name ':' TypeExpression NewLine => ClassMemberDeclarator.NewAbstractProperty(ClassMemberAccessibility.Public, $2, False, $4, @@)
    'abstract' Name '!' ':' TypeExpression NewLine => ClassMemberDeclarator.NewAbstractProperty(ClassMemberAccessibility.Public, $2, True, $5, @@)

    ClassMemberAccessibility Name ':' TypeExpression '=>' TestExpression NewLine => ClassMemberDeclarator.NewProperty($1, False, $2, $4, $6, @@)
    ClassMemberAccessibility Name ':' TypeExpression NewLine => ClassMemberDeclarator.NewPropertyField($1, False, $2, False, $4, None, @@)
    ClassMemberAccessibility Name ':' TypeExpression '=' TestExpression NewLine => ClassMemberDeclarator.NewPropertyField($1, False, $2, False, $4, $6, @@)
    ClassMemberAccessibility Name '!' ':' TypeExpression NewLine => ClassMemberDeclarator.NewPropertyField($1, False, $2, True, $5, None, @@)
    ClassMemberAccessibility Name '!' ':' TypeExpression '=' TestExpression NewLine => ClassMemberDeclarator.NewPropertyField($1, False, $2, True, $5, $7, @@)
    ClassMemberAccessibility Name ':' TypeExpression 'with' NewLine Indent 'get' ClassMethodBody Unindent => ClassMemberDeclarator.NewPropertyBlock($1, False, $2, $4, $9, None, @@)
    ClassMemberAccessibility Name ':' TypeExpression 'with' NewLine Indent 'get' ClassMethodBody 'set' ClassMethodBody Unindent => ClassMemberDeclarator.NewPropertyBlock($1, False, $2, $4, $9, $11, @@)
    ClassMemberAccessibility 'static' Name ':' TypeExpression '=>' TestExpression NewLine => ClassMemberDeclarator.NewProperty($1, True, $3, $5, $7, @@)
    ClassMemberAccessibility 'static' Name ':' TypeExpression NewLine => ClassMemberDeclarator.NewPropertyField($1, True, $3, False, $5, None, @@)
    ClassMemberAccessibility 'static' Name ':' TypeExpression '=' TestExpression NewLine => ClassMemberDeclarator.NewPropertyField($1, True, $3, False, $5, $7, @@)
    ClassMemberAccessibility 'static' Name '!' ':' TypeExpression NewLine => ClassMemberDeclarator.NewPropertyField($1, True, $3, True, $6, None, @@)
    ClassMemberAccessibility 'static' Name '!' ':' TypeExpression '=' TestExpression NewLine => ClassMemberDeclarator.NewPropertyField($1, True, $3, True, $6, $8, @@)
    ClassMemberAccessibility 'static' Name ':' TypeExpression 'with' NewLine Indent 'get' ClassMethodBody Unindent => ClassMemberDeclarator.NewPropertyBlock($1, True, $3, $5, $10, None, @@)
    ClassMemberAccessibility 'static' Name ':' TypeExpression 'with' NewLine Indent 'get' ClassMethodBody 'set' ClassMethodBody Unindent => ClassMemberDeclarator.NewPropertyBlock($1, True, $3, $5, $10, $12, @@)
    ClassMemberAccessibility ClassMemberVirtualModifier Name ':' TypeExpression '=>' TestExpression NewLine => ClassMemberDeclarator.NewVirtualProperty($1, $2, $3, $5, $7, @@)
    ClassMemberAccessibility ClassMemberVirtualModifier Name ':' TypeExpression NewLine => ClassMemberDeclarator.NewVirtualPropertyField($1, $2, $3, False, $5, None, @@)
    ClassMemberAccessibility ClassMemberVirtualModifier Name ':' TypeExpression '=' TestExpression NewLine => ClassMemberDeclarator.NewVirtualPropertyField($1, $2, $3, False, $5, $7, @@)
    ClassMemberAccessibility ClassMemberVirtualModifier Name '!' ':' TypeExpression NewLine => ClassMemberDeclarator.NewVirtualPropertyField($1, $2, $3, True, $6, None, @@)
    ClassMemberAccessibility ClassMemberVirtualModifier Name '!' ':' TypeExpression '=' TestExpression NewLine => ClassMemberDeclarator.NewVirtualPropertyField($1, $2, $3, True, $6, $8, @@)
    ClassMemberAccessibility ClassMemberVirtualModifier Name ':' TypeExpression 'with' NewLine Indent 'get' ClassMethodBody Unindent => ClassMemberDeclarator.NewVirtualPropertyBlock($1, $2, $3, $5, $10, None, @@)
    ClassMemberAccessibility ClassMemberVirtualModifier Name ':' TypeExpression 'with' NewLine Indent 'get' ClassMethodBody 'set' ClassMethodBody Unindent => ClassMemberDeclarator.NewVirtualPropertyBlock($1, $2, $3, $5, $10, $12, @@)
    ClassMemberAccessibility 'abstract' Name ':' TypeExpression NewLine => ClassMemberDeclarator.NewAbstractProperty($1, $3, False, $5, @@)
    ClassMemberAccessibility 'abstract' Name '!' ':' TypeExpression NewLine => ClassMemberDeclarator.NewAbstractProperty($1, $3, True, $6, @@)

    TypeExpression '::' Name ':' TypeExpression '=>' TestExpression NewLine => ClassMemberDeclarator.NewExplicitPropertyImpl($1, $3, $5, $7, @@)
    TypeExpression '::' Name ':' TypeExpression NewLine => ClassMemberDeclarator.NewExplicitPropertyImplField($1, $3, False, $5, None, @@)
    TypeExpression '::' Name ':' TypeExpression '=' TestExpression NewLine => ClassMemberDeclarator.NewExplicitPropertyImplField($1, $3, False, $5, $7, @@)
    TypeExpression '::' Name '!' ':' TypeExpression NewLine => ClassMemberDeclarator.NewExplicitPropertyImplField($1, $3, True, $6, None, @@)
    TypeExpression '::' Name '!' ':' TypeExpression '=' TestExpression NewLine => ClassMemberDeclarator.NewExplicitPropertyImplField($1, $3, True, $6, $8, @@)
    TypeExpression '::' Name ':' TypeExpression 'with' NewLine Indent 'get' ClassMethodBody Unindent => ClassMemberDeclarator.NewExplicitPropertyImplBlock($1, $3, $5, $10, None, @@)
    TypeExpression '::' Name ':' TypeExpression 'with' NewLine Indent 'get' ClassMethodBody 'set' ClassMethodBody Unindent => ClassMemberDeclarator.NewExplicitPropertyImplBlock($1, $3, $5, $10, $12, @@)

    'this' '[' ParameterList ']' ':' TypeExpression '=>' TestExpression NewLine => ClassMemberDeclarator.NewIndexer(ClassMemberAccessibility.Public, $3, $6, $8, @@)
    'this' '[' ParameterList ']' ':' TypeExpression 'with' NewLine Indent 'get' ClassMethodBody Unindent => ClassMemberDeclarator.NewIndexerBlock(ClassMemberAccessibility.Public, $3, $6, $11, None, @@)
    'this' '[' ParameterList ']' ':' TypeExpression 'with' NewLine Indent 'get' ClassMethodBody 'set' ClassMethodBody Unindent => ClassMemberDeclarator.NewIndexerBlock(ClassMemberAccessibility.Public, $3, $6, $11, $13, @@)
    ClassMemberVirtualModifier 'this' '[' ParameterList ']' ':' TypeExpression '=>' TestExpression NewLine => ClassMemberDeclarator.NewVirtualIndexer(ClassMemberAccessibility.Public, $1, $4, $7, $9, @@)
    ClassMemberVirtualModifier 'this' '[' ParameterList ']' ':' TypeExpression 'with' NewLine Indent 'get' ClassMethodBody Unindent => ClassMemberDeclarator.NewVirtualIndexerBlock(ClassMemberAccessibility.Public, $1, $4, $7, $12, None, @@)
    ClassMemberVirtualModifier 'this' '[' ParameterList ']' ':' TypeExpression 'with' NewLine Indent 'get' ClassMethodBody 'set' ClassMethodBody Unindent => ClassMemberDeclarator.NewVirtualIndexerBlock(ClassMemberAccessibility.Public, $1, $4, $7, $12, $14, @@)
    'abstract' 'this' '[' ParameterList ']' ':' TypeExpression NewLine => ClassMemberDeclarator.NewAbstractIndexer(ClassMemberAccessibility.Public, $4, False, $7, @@)
    'abstract' 'this' '[' ParameterList ']' '!' ':' TypeExpression NewLine => ClassMemberDeclarator.NewAbstractIndexer(ClassMemberAccessibility.Public, $4, True, $8, @@)

    ClassMemberAccessibility 'this' '[' ParameterList ']' ':' TypeExpression '=>' TestExpression NewLine => ClassMemberDeclarator.NewIndexer($1, $4, $7, $9, @@)
    ClassMemberAccessibility 'this' '[' ParameterList ']' ':' TypeExpression 'with' NewLine Indent 'get' ClassMethodBody Unindent => ClassMemberDeclarator.NewIndexerBlock($1, $4, $7, $12, None, @@)
    ClassMemberAccessibility 'this' '[' ParameterList ']' ':' TypeExpression 'with' NewLine Indent 'get' ClassMethodBody 'set' ClassMethodBody Unindent => ClassMemberDeclarator.NewIndexerBlock($1, $4, $7, $12, $14, @@)
    ClassMemberAccessibility ClassMemberVirtualModifier 'this' '[' ParameterList ']' ':' TypeExpression '=>' TestExpression NewLine => ClassMemberDeclarator.NewVirtualIndexer($1, $2, $5, $8, $10, @@)
    ClassMemberAccessibility ClassMemberVirtualModifier 'this' '[' ParameterList ']' ':' TypeExpression 'with' NewLine Indent 'get' ClassMethodBody Unindent => ClassMemberDeclarator.NewVirtualIndexerBlock($1, $2, $5, $8, $13, None, @@)
    ClassMemberAccessibility ClassMemberVirtualModifier 'this' '[' ParameterList ']' ':' TypeExpression 'with' NewLine Indent 'get' ClassMethodBody 'set' ClassMethodBody Unindent => ClassMemberDeclarator.NewVirtualIndexerBlock($1, $2, $5, $8, $13, $15, @@)
    ClassMemberAccessibility 'abstract' 'this' '[' ParameterList ']' ':' TypeExpression NewLine => ClassMemberDeclarator.NewAbstractIndexer($1, $5, False, $8, @@)
    ClassMemberAccessibility 'abstract' 'this' '[' ParameterList ']' '!' ':' TypeExpression NewLine => ClassMemberDeclarator.NewAbstractIndexer($1, $5, True, $9, @@)

    TypeExpression '::' 'this' '[' ParameterList ']' ':' TypeExpression '=>' TestExpression NewLine => ClassMemberDeclarator.NewExplicitIndexerImpl($1, $5, $8, $10, @@)
    TypeExpression '::' 'this' '[' ParameterList ']' ':' TypeExpression 'with' NewLine Indent 'get' ClassMethodBody Unindent => ClassMemberDeclarator.NewExplicitIndexerImplBlock($1, $5, $8, $13, None, @@)
    TypeExpression '::' 'this' '[' ParameterList ']' ':' TypeExpression 'with' NewLine Indent 'get' ClassMethodBody 'set' ClassMethodBody Unindent => ClassMemberDeclarator.NewExplicitIndexerImplBlock($1, $5, $8, $13, $15, @@)

    'def' Name '(' ParameterList ')' ClassMethodBody => ClassMemberDeclarator.NewMethod(ClassMemberAccessibility.Public, False, False, $2, $4, None, $6, @@)
    'def' Name '(' ParameterList ')' '->' TypeExpression ClassMethodBody => ClassMemberDeclarator.NewMethod(ClassMemberAccessibility.Public, False, False, $2, $4, $7, $8, @@)
    'async' 'def' Name '(' ParameterList ')' ClassMethodBody => ClassMemberDeclarator.NewMethod(ClassMemberAccessibility.Public, True, False, $3, $5, None, $7, @@)
    'async' 'def' Name '(' ParameterList ')' '->' TypeExpression ClassMethodBody => ClassMemberDeclarator.NewMethod(ClassMemberAccessibility.Public, True, False, $3, $5, $8, $9, @@)
    'static' 'def' Name '(' ParameterList ')' ClassMethodBody => ClassMemberDeclarator.NewMethod(ClassMemberAccessibility.Private, False, True, $3, $5, None, $7, @@)
    'static' 'def' Name '(' ParameterList ')' '->' TypeExpression ClassMethodBody => ClassMemberDeclarator.NewMethod(ClassMemberAccessibility.Private, False, True, $3, $5, $8, $9, @@)
    'async' 'static' 'def' Name '(' ParameterList ')' ClassMethodBody => ClassMemberDeclarator.NewMethod(ClassMemberAccessibility.Private, True, True, $4, $6, None, $8, @@)
    'async' 'static' 'def' Name '(' ParameterList ')' '->' TypeExpression ClassMethodBody => ClassMemberDeclarator.NewMethod(ClassMemberAccessibility.Private, True, True, $4, $6, $9, $10, @@)
    ClassMemberVirtualModifier Name '(' ParameterList ')' ClassMethodBody => ClassMemberDeclarator.NewVirtualMethod(ClassMemberAccessibility.Public, False, $1, $2, $4, None, $6, @@)
    ClassMemberVirtualModifier Name '(' ParameterList ')' '->' TypeExpression ClassMethodBody => ClassMemberDeclarator.NewVirtualMethod(ClassMemberAccessibility.Public, False, $1, $2, $4, $7, $8, @@)
    'async' ClassMemberVirtualModifier Name '(' ParameterList ')' ClassMethodBody => ClassMemberDeclarator.NewVirtualMethod(ClassMemberAccessibility.Public, True, $2, $3, $5, None, $7, @@)
    'async' ClassMemberVirtualModifier Name '(' ParameterList ')' '->' TypeExpression ClassMethodBody => ClassMemberDeclarator.NewVirtualMethod(ClassMemberAccessibility.Public, True, $2, $3, $5, $8, $9, @@)
    'abstract' Name '(' ParameterList ')' NewLine => ClassMemberDeclarator.NewAbstractMethod(ClassMemberAccessibility.Public, $2, $4, None, @@)
    'abstract' Name '(' ParameterList ')' '->' TypeExpression NewLine => ClassMemberDeclarator.NewAbstractMethod(ClassMemberAccessibility.Public, $2, $4, $7, @@)

    'def' TypeExpression '::' Name '(' ParameterList ')' ClassMethodBody => ClassMemberDeclarator.NewExplicitMethodImpl(False, $2, $4, $6, None, $8, @@)
    'def' TypeExpression '::' Name '(' ParameterList ')' '->' TypeExpression ClassMethodBody => ClassMemberDeclarator.NewExplicitMethodImpl(False, $2, $4, $6, $9, $10, @@)
    'async' 'def' TypeExpression '::' Name '(' ParameterList ')' ClassMethodBody => ClassMemberDeclarator.NewExplicitMethodImpl(True, $3, $5, $7, None, $9, @@)
    'async' 'def' TypeExpression '::' Name '(' ParameterList ')' '->' TypeExpression ClassMethodBody => ClassMemberDeclarator.NewExplicitMethodImpl(True, $3, $5, $7, $10, $11, @@)

    ClassMemberAccessibility 'def' Name '(' ParameterList ')' ClassMethodBody => ClassMemberDeclarator.NewMethod($1, False, False, $3, $5, None, $7, @@)
    ClassMemberAccessibility 'def' Name '(' ParameterList ')' '->' TypeExpression ClassMethodBody => ClassMemberDeclarator.NewMethod($1, False, False, $3, $5, $8, $9, @@)
    ClassMemberAccessibility 'async' 'def' Name '(' ParameterList ')' ClassMethodBody => ClassMemberDeclarator.NewMethod($1, True, False, $4, $6, None, $8, @@)
    ClassMemberAccessibility 'async' 'def' Name '(' ParameterList ')' '->' TypeExpression ClassMethodBody => ClassMemberDeclarator.NewMethod($1, True, False, $4, $6, $9, $10, @@)
    ClassMemberAccessibility 'static' 'def' Name '(' ParameterList ')' ClassMethodBody => ClassMemberDeclarator.NewMethod($1, False, True, $4, $6, None, $8, @@)
    ClassMemberAccessibility 'static' 'def' Name '(' ParameterList ')' '->' TypeExpression ClassMethodBody => ClassMemberDeclarator.NewMethod($1, False, True, $4, $6, $9, $10, @@)
    ClassMemberAccessibility 'async' 'static' 'def' Name '(' ParameterList ')' ClassMethodBody => ClassMemberDeclarator.NewMethod($1, True, True, $5, $7, None, $9, @@)
    ClassMemberAccessibility 'async' 'static' 'def' Name '(' ParameterList ')' '->' TypeExpression ClassMethodBody => ClassMemberDeclarator.NewMethod($1, True, True, $5, $7, $10, $11, @@)
    ClassMemberAccessibility ClassMemberVirtualModifier Name '(' ParameterList ')' ClassMethodBody => ClassMemberDeclarator.NewVirtualMethod($1, False, $2, $3, $5, None, $7, @@)
    ClassMemberAccessibility ClassMemberVirtualModifier Name '(' ParameterList ')' '->' TypeExpression ClassMethodBody => ClassMemberDeclarator.NewVirtualMethod($1, False, $2, $3, $5, $8, $9, @@)
    ClassMemberAccessibility 'async' ClassMemberVirtualModifier Name '(' ParameterList ')' ClassMethodBody => ClassMemberDeclarator.NewVirtualMethod($1, True, $3, $4, $6, None, $8, @@)
    ClassMemberAccessibility 'async' ClassMemberVirtualModifier Name '(' ParameterList ')' '->' TypeExpression ClassMethodBody => ClassMemberDeclarator.NewVirtualMethod($1, True, $3, $4, $6, $9, $10, @@)
    ClassMemberAccessibility 'abstract' Name '(' ParameterList ')' NewLine => ClassMemberDeclarator.NewAbstractMethod($1, $3, $5, None, @@)
    ClassMemberAccessibility 'abstract' Name '(' ParameterList ')' '->' TypeExpression NewLine => ClassMemberDeclarator.NewAbstractMethod($1, $3, $5, $8, @@)

    'def' 'new' '(' ParameterList ')' ClassMethodBody => ClassMemberDeclarator.NewConstructor(ClassMemberAccessibility.Public, $4, $6, @@)
    'def' 'new' '(' ParameterList ')' 'with' 'this' ArgumentList ClassMethodBody => ClassMemberDeclarator.NewConstructorWithThis(ClassMemberAccessibility.Public, $4, $8, $9, @@)
    'def' 'new' '(' ParameterList ')' 'with' 'base' ArgumentList ClassMethodBody => ClassMemberDeclarator.NewConstructorWithBase(ClassMemberAccessibility.Public, $4, $8, $9, @@)
    ClassMemberAccessibility 'def' 'new' '(' ParameterList ')' ClassMethodBody => ClassMemberDeclarator.NewConstructor($1, $5, $7, @@)
    ClassMemberAccessibility 'def' 'new' '(' ParameterList ')' 'with' 'this' ArgumentList ClassMethodBody => ClassMemberDeclarator.NewConstructorWithThis($1, $5, $9, $10, @@)
    ClassMemberAccessibility 'def' 'new' '(' ParameterList ')' 'with' 'base' ArgumentList ClassMethodBody => ClassMemberDeclarator.NewConstructorWithBase($1, $5, $9, $10, @@)
    'static' 'new' '(' ')' ClassMethodBody => ClassMemberDeclarator.NewStaticConstructor($5, @@)

EnumDeclarator as EnumDeclarator:
    Name ':' 'one' 'of' NewLine Indent EnumItemDeclarator+ Unindent => EnumDeclarator.New(False, $1, False, $7, @@)
    Name ':' 'reversed' 'one' 'of' NewLine Indent EnumItemDeclarator+ Unindent => EnumDeclarator.New(False, $1, True, $8, @@)
    'public' Name ':' 'one' 'of' NewLine Indent EnumItemDeclarator+ Unindent => EnumDeclarator.New(False, $2, False, $8, @@)
    'public' Name ':' 'reversed' 'one' 'of' NewLine Indent EnumItemDeclarator+ Unindent => EnumDeclarator.New(False, $2, True, $9, @@)
    'internal' Name ':' 'one' 'of' NewLine Indent EnumItemDeclarator+ Unindent => EnumDeclarator.New(True, $2, False, $8, @@)
    'internal' Name ':' 'reversed' 'one' 'of' NewLine Indent EnumItemDeclarator+ Unindent => EnumDeclarator.New(True, $2, True, $9, @@)

EnumTypeDeclarator as EnumDeclarator:
    'enum' Name ':' NewLine Indent EnumItemDeclarator+ Unindent => EnumDeclarator.New(False, $2, False, $6, @@)
    'enum' Name ':' 'reversed' NewLine Indent EnumItemDeclarator+ Unindent => EnumDeclarator.New(False, $2, False, $7, @@)
    'public' 'enum' Name ':' NewLine Indent EnumItemDeclarator+ Unindent => EnumDeclarator.New(False, $3, False, $7, @@)
    'public' 'enum' Name ':' 'reversed' NewLine Indent EnumItemDeclarator+ Unindent => EnumDeclarator.New(False, $3, False, $8, @@)
    'internal' 'enum' Name ':' NewLine Indent EnumItemDeclarator+ Unindent => EnumDeclarator.New(True, $3, False, $7, @@)
    'internal' 'enum' Name ':' 'reversed' NewLine Indent EnumItemDeclarator+ Unindent => EnumDeclarator.New(True, $3, False, $8, @@)

StructDeclarator as StructDeclarator:
    Name '=' '(' StructFieldDeclarator %+ ',' ')' NewLine => StructDeclarator.New(False, $1, $4, False, @@)
    Name '=' 'struct' '(' StructFieldDeclarator %+ ',' ')' NewLine => StructDeclarator.New(False, $1, $5, True, @@)
    'public' Name '=' '(' StructFieldDeclarator %+ ',' ')' NewLine => StructDeclarator.New(False, $2, $5, False, @@)
    'public' Name '=' 'struct' '(' StructFieldDeclarator %+ ',' ')' NewLine => StructDeclarator.New(False, $2, $6, True, @@)
    'internal' Name '=' '(' StructFieldDeclarator %+ ',' ')' NewLine => StructDeclarator.New(True, $2, $5, False, @@)
    'internal' Name '=' 'struct' '(' StructFieldDeclarator %+ ',' ')' NewLine => StructDeclarator.New(True, $2, $6, True, @@)

StructTypeDeclarator as StructDeclarator:
    'type' Name '=' '(' StructFieldDeclarator %+ ',' ')' NewLine => StructDeclarator.New(False, $2, $5, False, @@)
    'type' Name '=' 'struct' '(' StructFieldDeclarator %+ ',' ')' NewLine => StructDeclarator.New(False, $2, $6, True, @@)
    'public' 'type' Name '=' '(' StructFieldDeclarator %+ ',' ')' NewLine => StructDeclarator.New(False, $3, $6, False, @@)
    'public' 'type' Name '=' 'struct' '(' StructFieldDeclarator %+ ',' ')' NewLine => StructDeclarator.New(False, $3, $7, True, @@)
    'internal' 'type' Name '=' '(' StructFieldDeclarator %+ ',' ')' NewLine => StructDeclarator.New(True, $3, $6, False, @@)
    'internal' 'type' Name '=' 'struct' '(' StructFieldDeclarator %+ ',' ')' NewLine => StructDeclarator.New(True, $3, $7, True, @@)

UnionDeclarator as UnionDeclarator:
    Name ':' NewLine Indent UnionCaseDeclaratorSuite Unindent => UnionDeclarator.New(False, $1, $5, @@)
    'public' Name ':' NewLine Indent UnionCaseDeclaratorSuite Unindent => UnionDeclarator.New(False, $2, $6, @@)
    'internal' Name ':' NewLine Indent UnionCaseDeclaratorSuite Unindent => UnionDeclarator.New(True, $2, $6, @@)

UnionTypeDeclarator as UnionDeclarator:
    'union' Name ':' NewLine Indent UnionCaseDeclaratorSuite Unindent => UnionDeclarator.New(False, $2, $6, @@)
    'public' 'union' Name ':' NewLine Indent UnionCaseDeclaratorSuite Unindent => UnionDeclarator.New(False, $3, $7, @@)
    'internal' 'union' Name ':' NewLine Indent UnionCaseDeclaratorSuite Unindent => UnionDeclarator.New(True, $3, $7, @@)

VisitorDeclarator as VisitorDeclarator:
    Name '.' Name '(' ParameterList ')' NewLine => VisitorDeclarator.New(False, $1, $3, $5, None, @@)
    Name '.' Name '(' ParameterList ')' '->' TypeExpression NewLine => VisitorDeclarator.New(False, $1, $3, $5, $8, @@)
    'public' Name '.' Name '(' ParameterList ')' NewLine => VisitorDeclarator.New(False, $2, $4, $6, None, @@)
    'public' Name '.' Name '(' ParameterList ')' '->' TypeExpression NewLine => VisitorDeclarator.New(False, $2, $4, $6, $9, @@)
    'internal' Name '.' Name '(' ParameterList ')' NewLine => VisitorDeclarator.New(True, $2, $4, $6, None, @@)
    'internal' Name '.' Name '(' ParameterList ')' '->' TypeExpression NewLine => VisitorDeclarator.New(True, $2, $4, $6, $9, @@)

VisitorTypeDeclarator as VisitorDeclarator:
    'type' Name '.' Name '(' ParameterList ')' NewLine => VisitorDeclarator.New(False, $2, $4, $6, None, @@)
    'type' Name '.' Name '(' ParameterList ')' '->' TypeExpression NewLine => VisitorDeclarator.New(False, $2, $4, $6, $9, @@)
    'public' 'type' Name '.' Name '(' ParameterList ')' NewLine => VisitorDeclarator.New(False, $3, $5, $7, None, @@)
    'public' 'type' Name '.' Name '(' ParameterList ')' '->' TypeExpression NewLine => VisitorDeclarator.New(False, $3, $5, $7, $10, @@)
    'internal' 'type' Name '.' Name '(' ParameterList ')' NewLine => VisitorDeclarator.New(True, $3, $5, $7, None, @@)
    'internal' 'type' Name '.' Name '(' ParameterList ')' '->' TypeExpression NewLine => VisitorDeclarator.New(True, $3, $5, $7, $10, @@)

InterfaceDeclarator as InterfaceDeclarator:
    'interface' Name ':' 'pass' NewLine => InterfaceDeclarator.New(False, $2, default([TypeExpression]), default([InterfaceMemberDeclarator]), @@)
    'interface' Name ':' NewLine Indent 'pass' NewLine Unindent => InterfaceDeclarator.New(False, $2, default([TypeExpression]), default([InterfaceMemberDeclarator]), @@)
    'interface' Name ':' NewLine Indent InterfaceMemberDeclarator+ Unindent => InterfaceDeclarator.New(False, $2, default([TypeExpression]), $6, @@)
    'interface' Name '(' TypeExpression % ',' ')' ':' 'pass' NewLine => InterfaceDeclarator.New(False, $2, $4, default([InterfaceMemberDeclarator]), @@)
    'interface' Name '(' TypeExpression % ',' ')' ':' NewLine Indent 'pass' NewLine Unindent => InterfaceDeclarator.New(False, $2, $4, default([InterfaceMemberDeclarator]), @@)
    'interface' Name '(' TypeExpression % ',' ')' ':' NewLine Indent InterfaceMemberDeclarator+ Unindent => InterfaceDeclarator.New(False, $2, $4, $9, @@)

    'public' 'interface' Name ':' 'pass' NewLine => InterfaceDeclarator.New(False, $3, default([TypeExpression]), default([InterfaceMemberDeclarator]), @@)
    'public' 'interface' Name ':' NewLine Indent 'pass' NewLine Unindent => InterfaceDeclarator.New(False, $3, default([TypeExpression]), default([InterfaceMemberDeclarator]), @@)
    'public' 'interface' Name ':' NewLine Indent InterfaceMemberDeclarator+ Unindent => InterfaceDeclarator.New(False, $3, default([TypeExpression]), $7, @@)
    'public' 'interface' Name '(' TypeExpression % ',' ')' ':' 'pass' NewLine => InterfaceDeclarator.New(False, $3, $5, default([InterfaceMemberDeclarator]), @@)
    'public' 'interface' Name '(' TypeExpression % ',' ')' ':' NewLine Indent 'pass' NewLine Unindent => InterfaceDeclarator.New(False, $3, $5, default([InterfaceMemberDeclarator]), @@)
    'public' 'interface' Name '(' TypeExpression % ',' ')' ':' NewLine Indent InterfaceMemberDeclarator+ Unindent => InterfaceDeclarator.New(False, $3, $5, $10, @@)

    'internal' 'interface' Name ':' 'pass' NewLine => InterfaceDeclarator.New(True, $3, default([TypeExpression]), default([InterfaceMemberDeclarator]), @@)
    'internal' 'interface' Name ':' NewLine Indent 'pass' NewLine Unindent => InterfaceDeclarator.New(True, $3, default([TypeExpression]), default([InterfaceMemberDeclarator]), @@)
    'internal' 'interface' Name ':' NewLine Indent InterfaceMemberDeclarator+ Unindent => InterfaceDeclarator.New(True, $3, default([TypeExpression]), $7, @@)
    'internal' 'interface' Name '(' TypeExpression % ',' ')' ':' 'pass' NewLine => InterfaceDeclarator.New(True, $3, $5, default([InterfaceMemberDeclarator]), @@)
    'internal' 'interface' Name '(' TypeExpression % ',' ')' ':' NewLine Indent 'pass' NewLine Unindent => InterfaceDeclarator.New(True, $3, $5, default([InterfaceMemberDeclarator]), @@)
    'internal' 'interface' Name '(' TypeExpression % ',' ')' ':' NewLine Indent InterfaceMemberDeclarator+ Unindent => InterfaceDeclarator.New(True, $3, $5, $10, @@)

ClassDeclarator as ClassDeclarator:
    'public' ClassVirtualModifier Name ':' 'pass' NewLine => ClassDeclarator.New(False, $2, $3, default([TypeExpression]), default([ClassMemberDeclarator]), @@)
    'public' ClassVirtualModifier Name ':' NewLine Indent 'pass' NewLine Unindent => ClassDeclarator.New(False, $2, $3, default([TypeExpression]), default([ClassMemberDeclarator]), @@)
    'public' ClassVirtualModifier Name ':' NewLine Indent ClassMemberDeclarator+ Unindent => ClassDeclarator.New(False, $2, $3, default([TypeExpression]), $7, @@)

    'public' ClassVirtualModifier Name '(' TypeExpression % ',' ')' ':' 'pass' NewLine => ClassDeclarator.New(False, $2, $3, $5, default([ClassMemberDeclarator]), @@)
    'public' ClassVirtualModifier Name '(' TypeExpression % ',' ')' ':' NewLine Indent 'pass' NewLine Unindent => ClassDeclarator.New(False, $2, $3, $5, default([ClassMemberDeclarator]), @@)
    'public' ClassVirtualModifier Name '(' TypeExpression % ',' ')' ':' NewLine Indent ClassMemberDeclarator+ Unindent => ClassDeclarator.New(False, $2, $3, $5, $10, @@)

    'internal' ClassVirtualModifier Name ':' 'pass' NewLine => ClassDeclarator.New(True, $2, $3, default([TypeExpression]), default([ClassMemberDeclarator]), @@)
    'internal' ClassVirtualModifier Name ':' NewLine Indent 'pass' NewLine Unindent => ClassDeclarator.New(True, $2, $3, default([TypeExpression]), default([ClassMemberDeclarator]), @@)
    'internal' ClassVirtualModifier Name ':' NewLine Indent ClassMemberDeclarator+ Unindent => ClassDeclarator.New(True, $2, $3, default([TypeExpression]), $7, @@)

    'internal' ClassVirtualModifier Name '(' TypeExpression % ',' ')' ':' 'pass' NewLine => ClassDeclarator.New(True, $2, $3, $5, default([ClassMemberDeclarator]), @@)
    'internal' ClassVirtualModifier Name '(' TypeExpression % ',' ')' ':' NewLine Indent 'pass' NewLine Unindent => ClassDeclarator.New(True, $2, $3, $5, default([ClassMemberDeclarator]), @@)
    'internal' ClassVirtualModifier Name '(' TypeExpression % ',' ')' ':' NewLine Indent ClassMemberDeclarator+ Unindent => ClassDeclarator.New(True, $2, $3, $5, $10, @@)

TypeDeclarator as TypeDeclarator:
    EnumDeclarator => TypeDeclarator.NewEnum($1.IsInternal, $1.Name, $1, @1)
    EnumTypeDeclarator => TypeDeclarator.NewEnum($1.IsInternal, $1.Name, $1, @1)
    StructDeclarator => TypeDeclarator.NewStruct($1.IsInternal, $1.Name, $1, @1)
    StructTypeDeclarator => TypeDeclarator.NewStruct($1.IsInternal, $1.Name, $1, @1)
    UnionDeclarator => TypeDeclarator.NewUnion($1.IsInternal, $1.Name, $1, @1)
    UnionTypeDeclarator => TypeDeclarator.NewUnion($1.IsInternal, $1.Name, $1, @1)
    VisitorDeclarator => TypeDeclarator.NewVisitor($1.IsInternal, $1.Name, $1, @1)
    VisitorTypeDeclarator => TypeDeclarator.NewVisitor($1.IsInternal, $1.Name, $1, @1)
    InterfaceDeclarator => TypeDeclarator.NewInterface($1.IsInternal, $1.Name, $1, @1)
    ClassDeclarator => TypeDeclarator.NewClass($1.IsInternal, $1.Name, $1, @1)

TypeDeclaration as TypeDeclaration:
    TypeDeclarator* => TypeDeclaration.New($1, @@)
